﻿#include "mainwidget.h"
#include "ui_mainwidget.h"
#include <QPainter>
#include <QFileDialog>
#include <QModelIndexList>
#include <QMessageBox>
#include <QDesktopWidget>
#include <QSettings>
#include <QUuid>
#include <QDebug>

#include "imageitemdelegate.h"
#include "mergedialog.h"
#include "ps.h"

MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    mModel = new QtRowTableModel<ImageItem>(true,this);

    QStringList heads;
    heads << QStringLiteral("序号")
          << QStringLiteral("预览")
          << QStringLiteral("尺寸")
          << QStringLiteral("路径");

    mModel->setHeaderLabels(heads);

    ui->tableView->verticalHeader()->setDefaultSectionSize(70);
    ui->tableView->setModel(mModel);
    ui->tableView->setColumnWidth(0,20);
    ui->tableView->setColumnWidth(1,120);
    ui->tableView->horizontalHeader()->setVisible(true);
    ui->tableView->setItemDelegateForColumn(1,new ImageItemDelegate(this));

    connect(ui->tableView,&QTableView::clicked,this,[=](QModelIndex index){
        if(index.isValid()){
            int r = index.row();

            ImageItemPtr imgItemPtr = mModel->get(r);
            if(imgItemPtr){
                setCurrentImg(imgItemPtr);
            }
        }
    });

    QSettings settings(QSettings::NativeFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

    int leftMargin = settings.value("leftMargin", 20).toInt();
    int rightMargin = settings.value("rightMargin", 20).toInt();
    int topMargin = settings.value("topMargin", 20).toInt();
    int bottomMargin = settings.value("bottomMargin", 20).toInt();
    int space = settings.value("space", 10).toInt();

    ui->sb_left->setValue(leftMargin);
    ui->sb_right->setValue(rightMargin);
    ui->sb_top->setValue(topMargin);
    ui->sb_bottom->setValue(bottomMargin);
    ui->sb_space->setValue(space);
}

MainWidget::~MainWidget()
{
    QSettings settings(QSettings::NativeFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
    settings.setValue("leftMargin", ui->sb_left->value());
    settings.setValue("rightMargin", ui->sb_right->value());
    settings.setValue("topMargin", ui->sb_top->value());
    settings.setValue("bottomMargin", ui->sb_bottom->value());
    settings.setValue("space", ui->sb_space->value());
    delete ui;
}

QImage MainWidget::MergeImageV(QList<QImage> images,int leftMargin,int rightMargin,int topMargin,int bottomMargin,int space)
{
    if(images.size() == 0) {
        return QImage();
    }

    int max_width = 0;
    int image_height=0;
    foreach(const QImage& img,images) //计算最大宽度
    {
        int width = img.width();
        if(width >max_width){
            max_width = img.width();
        }
    }

    for(int i = 0;i< images.size(); ++ i)
    {
        int height = images[i].height();
        int width = images[i].width();

        if(width < max_width) {
            height = qreal(max_width * height) / width;
            images[i] = images[i].scaled(max_width,height,Qt::KeepAspectRatio,Qt::SmoothTransformation);
        }

        image_height += (height + space) ;
    }

    int w = max_width + leftMargin + rightMargin;
    int h = image_height + topMargin + bottomMargin - space;
    qDebug() << "target image size:" <<  w << h << w * h;

    QImage result_image_v(w,h,QImage::Format_RGB32);
    result_image_v.fill(Qt::white);
    qDebug() << "image valiad" <<  result_image_v.size() << result_image_v.isNull();
    QPainter painter_v;
    qDebug() << "QPainter begin" <<  painter_v.begin(&result_image_v);
    painter_v.setRenderHint(QPainter::Antialiasing, true);
    int y_number=topMargin;

    foreach(auto img,images)
    {
        painter_v.drawImage(leftMargin,y_number,img);
        y_number += img.height() + space;
    }
    painter_v.end();
    return result_image_v;
}

QList<QImage> MainWidget::getImages()
{
    QList<QImage> images;
    int rowCount = mModel->rowCount();
    for(int i=0;i<rowCount;++i){
        ImageItemPtr itemPtr =  mModel->get(i);
        if(itemPtr) {
            QImage img = ps(itemPtr->image(),itemPtr->bright(),itemPtr->contrast(),itemPtr->staturate());
            images.append(img);
        }
    }
    return images;
}

void MainWidget::on_pbOpen_clicked()
{
    QStringList files = QFileDialog::getOpenFileNames(
                              this,
                              "Select one or more files to open",
                              "",
                              "Images (*.png *.jpg *.bmp *jpeg)");

    foreach(QString file,files){
        if(!file.isEmpty()){
            QFileInfo fi(file);
            QImage img;
            if(fi.isFile() && img.load(file)){
                ImageItemPtr item = ImageItemPtr(new ImageItem());
                item->setFile(file);
                item->setSize(img.size());
                item->setImage(img);
                item->setName(fi.baseName());
                mModel->add(item);
            }
        }
    }
}

void MainWidget::on_pbUp_clicked()
{
    QModelIndexList indexs = ui->tableView->selectionModel()->selectedRows();
    if(indexs.size() == 1) {
        int index = indexs.at(0).row();
        if(index>0){
            mModel->move(index,-1);
        }
    }
}

void MainWidget::on_pbDown_clicked()
{
    QModelIndexList indexs = ui->tableView->selectionModel()->selectedRows();
    if(indexs.size() == 1) {
        int index = indexs.at(0).row();
        if(index < mModel->rowCount()-1){
            mModel->move(index, 1);
        }
    }
}

void MainWidget::on_pbPreview_clicked()
{
    QList<QImage> images = getImages();
    QImage previewImg =  this->MergeImageV(images,
                                           ui->sb_left->value(),
                                           ui->sb_right->value(),
                                           ui->sb_top->value(),
                                           ui->sb_bottom->value(),
                                           ui->sb_space->value());

    if(previewImg.isNull()){
        QMessageBox::warning(this,QStringLiteral("警告"),QStringLiteral("暂无图片，无法合成！"));
        return;
    }

    if(!mPreview){
        auto rect = QApplication::desktop()->geometry();
        mPreview = new MergeDialog(this);
        mPreview->resize(1400,rect.height() - 200);
    }

    mPreview->show();
    mPreview->setImage(previewImg);
}

void MainWidget::on_pb_delete_clicked()
{
    QModelIndexList indexs = ui->tableView->selectionModel()->selectedRows();
    if(indexs.size() == 1) {
        int index = indexs.at(0).row();
        mModel->remove(index);
        m_currentImg = ImageItemPtr();
        ui->label_img->setPixmap(QPixmap());
    }
}

void MainWidget::on_pb_clear_pressed()
{
    mModel->clear();
    m_currentImg = ImageItemPtr();
    ui->label_img->setPixmap(QPixmap());
}

ImageItemPtr MainWidget::getCurrentImg() const
{
    return m_currentImg;
}

QImage MainWidget::ps(QImage img,int ld, int dbd,int bhd)
{
    QImage resultImg = img;
    if(ld){
        resultImg = AdjustBrightness(resultImg,ld);
    }
    if(dbd){
        resultImg = AdjustContrast(resultImg,dbd);
    }
    if(bhd){
        resultImg = AdjustSaturation(resultImg,bhd);
    }

    return resultImg;
}

void MainWidget::setCurrentImg(const ImageItemPtr &currentImg)
{
    if(m_currentImg == currentImg){
        return;
    }

    m_currentImg = ImageItemPtr();

    ui->slider_ld->setValue(currentImg->bright());
    ui->silider_dbd->setValue(currentImg->contrast());
    ui->slider_bhd->setValue(currentImg->staturate());

    ui->lb_ld->setText(QString::number(currentImg->bright()));
    ui->lb_dbd->setText(QString::number(currentImg->contrast()));
    ui->lb_bhd->setText(QString::number(currentImg->staturate()));

    m_currentImg = currentImg;

    QImage img = ps(m_currentImg->image(),m_currentImg->bright(),m_currentImg->contrast(),m_currentImg->staturate());
    QPixmap pixmap = QPixmap::fromImage(img);
    QSize size = ui->label_img->size();
    ui->label_img->setPixmap(pixmap.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation));
}

void MainWidget::on_slider_ld_valueChanged(int value)
{
    ui->lb_ld->setText(QString::number(value));

    if(m_currentImg){
        m_currentImg->setBright(value);

        QImage img = ps(m_currentImg->image(),m_currentImg->bright(),m_currentImg->contrast(),m_currentImg->staturate());
        QPixmap pixmap = QPixmap::fromImage(img);
        QSize size = ui->label_img->size();
        ui->label_img->setPixmap(pixmap.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation));
    }
}

void MainWidget::on_silider_dbd_valueChanged(int value)
{
    ui->lb_dbd->setText(QString::number(value));


    if(m_currentImg){
        m_currentImg->setContrast(value);

        QImage img = ps(m_currentImg->image(),m_currentImg->bright(),m_currentImg->contrast(),m_currentImg->staturate());
        QPixmap pixmap = QPixmap::fromImage(img);
        QSize size = ui->label_img->size();
        ui->label_img->setPixmap(pixmap.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation));
    }
}

void MainWidget::on_slider_bhd_valueChanged(int value)
{
    ui->lb_bhd->setText(QString::number(value));

    if(m_currentImg){
        m_currentImg->setStaturate(value);

        QImage img = ps(m_currentImg->image(),m_currentImg->bright(),m_currentImg->contrast(),m_currentImg->staturate());
        QPixmap pixmap = QPixmap::fromImage(img);
        QSize size = ui->label_img->size();
        ui->label_img->setPixmap(pixmap.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation));
    }
}
